#import "Repository.h"
#import "Cliente.h"

@interface Repository()
@property (nonatomic, strong) NSString* filePath;
@property (nonatomic, strong) SearchService* searchService;
@property (nonatomic, assign) SEL getModelsSelector;
@property (nonatomic, assign) SEL getInfoSelector;
@property (nonatomic, strong) ConvertFromDictionary convertFromDictionary;
@end

@implementation Repository

@synthesize filePath;
@synthesize searchService;
@synthesize getModelsSelector;
@synthesize getInfoSelector;
@synthesize convertFromDictionary;

+(Repository*)repositoryWithSearchService:(SearchService *)aSearchService modelName:(NSString *)modelName getModelsSelector:(SEL)aGetModelsSelector getInfoSelector:(SEL)aGetInfoSelector convertFromDictionary:(ConvertFromDictionary)aConvertFromDictionary {
    return [[Repository alloc] initWithSearchService:aSearchService modelName:modelName getModelsSelector:aGetModelsSelector getInfoSelector:aGetInfoSelector convertFromDictionary:aConvertFromDictionary];
}

-(id)initWithSearchService:(SearchService *)aSearchService modelName:(NSString *)modelName getModelsSelector:(SEL)aGetModelsSelector getInfoSelector:(SEL)aGetInfoSelector convertFromDictionary:(ConvertFromDictionary)aConvertFromDictionary {
    self = [super init];
    if (self) {
        self.searchService = aSearchService;
        self.filePath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:modelName] stringByAppendingPathExtension:@"plist"];
        self.getModelsSelector = aGetModelsSelector;
        self.getInfoSelector = aGetInfoSelector;
        self.convertFromDictionary = aConvertFromDictionary;
    }
    return self;
}

-(NSArray*)getModels:(BOOL)reload error:(NSError **)error {
    if (reload) {
        NSArray* models = [self.searchService performSelector:self.getModelsSelector withObject:(__bridge id)((void*)error)];
        if (*error) {
            return nil;
        }
        NSMutableArray* modelsToSave = [NSMutableArray arrayWithCapacity:[models count]];
        for (id<SelectableModel> model in models) {
            [modelsToSave addObject:[model toDictionary]];
        }
        [modelsToSave writeToFile:self.filePath atomically:YES];
        return models;
    } else {
        if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath]) {
            NSArray* modelsLoaded = [NSArray arrayWithContentsOfFile:self.filePath];
            if (modelsLoaded != nil && modelsLoaded.count > 0) {
                NSMutableArray* models = [NSMutableArray array];
                for (NSDictionary* modelLoaded in modelsLoaded) {
                    [models addObject:self.convertFromDictionary(modelLoaded)];
                }
                return models;
            }
        }
        return [self getModels:YES error:error];
    }
}

-(id<SelectableModel>)getModelById:(NSString *)idModel error:(NSError **)error {
    NSArray* models = [self getModels:NO error:error];
    if (!*error) {
        for (id<SelectableModel> model in models) {
            if ([model.id isEqualToString:idModel]) {
                return model;
            }
        }
    }
    return nil;
}

-(InfoBase*)getModelInfoById:(NSString *)idModel error:(NSError **)error {
    return [self.searchService performSelector:self.getInfoSelector withObject:idModel withObject:(__bridge id)((void*)error)];
}

@end
